{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 学生上机综合实验（一）- 进阶篇\n",
    "\n",
    "**目标：** 本实验旨在模拟一个真实的数据清洗与处理任务。你将综合运用字符串处理、循环、条件判断和函数封装等多种技能，将一批混乱的原始文本数据，转换成结构化、可用的信息，并最终生成一份格式化的报告。\n",
    "\n",
    "**场景：** 假设你是一个数据分析师助理，你从系统中导出了一批用户注册记录。然而，这些记录格式不一，充满了多余的空格、大小写错误，甚至还有一些无效数据。你的任务就是清理这些烂摊子！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 任务一：单条记录的深度解析与函数封装\n",
    "\n",
    "首先，我们来聚焦于如何处理单条复杂的记录。我们的目标是编写一个健壮的函数，该函数可以解析一条记录字符串，并以规范的字典格式返回提取出的信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.1 数据解析挑战\n",
    "\n",
    "请编写一个名为 `parse_user_record` 的函数，它接收一个字符串参数 `record_string`。该函数需要执行以下操作：\n",
    "\n",
    "1.  **初步清理**：去除输入字符串首尾的空白字符。\n",
    "2.  **格式验证**：检查清理后的字符串是否包含 `\"ID:\"` 和 `\"Email:\"` 这两个关键标识。如果任一标识不存在，说明是无效记录，函数应返回 `None`。\n",
    "3.  **数据分割**：以分号 `;` 为分隔符，将字符串分割成多个部分。\n",
    "4.  **信息提取与深度清理**：遍历分割后的每个部分，提取并清理以下字段：\n",
    "    *   **ID**: 提取 `ID:` 后面的数字部分，并去除任何潜在的空白。\n",
    "    *   **Name**: 提取 `Name:` 后面的姓名，格式化为“标题格式”（例如 `John Doe`）。\n",
    "    *   **Email**: 提取 `Email:` 后面的邮箱地址，全部转换为小写，并去除空白。\n",
    "    *   **Status**: 提取 `Status:` 后面的状态值，转换为小写。\n",
    "5.  **结构化返回**：将清理和格式化后的数据存入一个字典，并返回该字典。例如：`{'id': '10234', 'name': 'Jane Smith', 'email': 'jane.s@example.com', 'status': 'active'}`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "解析结果1: {'id': '10234', 'name': 'Jane Smith', 'email': 'jane.s@example.com', 'status': 'active'}\n",
      "解析结果2: None\n",
      "解析结果3: {'id': '20567', 'name': 'Peter Jones', 'email': 'peter@work.net', 'status': 'inactive'}\n"
     ]
    }
   ],
   "source": [
    "def parse_user_record(record_string):\n",
    "    \"\"\"解析单条用户记录字符串，返回一个包含信息的字典或None。\"\"\"\n",
    "    # 1. 初步清理\n",
    "    clean_string = record_string.strip()\n",
    "\n",
    "    # 2. 格式验证\n",
    "    if \"ID:\" not in clean_string or \"Email:\" not in clean_string:\n",
    "        return None\n",
    "\n",
    "    # 3. 数据分割\n",
    "    parts = clean_string.split(';')\n",
    "    \n",
    "    # 创建一个空字典来存储结果\n",
    "    user_data = {}\n",
    "\n",
    "    # 4. 信息提取与深度清理\n",
    "    for part in parts:\n",
    "        part = part.strip() # 清理每个部分的空白\n",
    "        if part.startswith(\"ID:\"):\n",
    "            user_data['id'] = part.removeprefix(\"ID:\").strip()\n",
    "        elif part.startswith(\"Name:\"):\n",
    "            user_data['name'] = part.removeprefix(\"Name:\").strip().title()\n",
    "        elif part.startswith(\"Email:\"):\n",
    "            user_data['email'] = part.removeprefix(\"Email:\").strip().lower()\n",
    "        elif part.startswith(\"Status:\"):\n",
    "            user_data['status'] = part.removeprefix(\"Status:\").strip().lower()\n",
    "        \n",
    "    # 5. 返回结构化数据\n",
    "    return user_data\n",
    "\n",
    "# --- 函数测试区 ---\n",
    "record1 = \"  ID: 10234; Name:  jANE sMITh  ; Email: JANE.S@example.com; Status: Active  \"\n",
    "record2 = \"  Invalid Record; Email: none@none.com \" # 缺少ID\n",
    "record3 = \"ID: 20567; Name: peter jones; Email: PETER@work.net; Status: Inactive\"\n",
    "\n",
    "parsed1 = parse_user_record(record1)\n",
    "parsed2 = parse_user_record(record2)\n",
    "parsed3 = parse_user_record(record3)\n",
    "\n",
    "print(f\"解析结果1: {parsed1}\")\n",
    "print(f\"解析结果2: {parsed2}\")\n",
    "print(f\"解析结果3: {parsed3}\")\n",
    "\n",
    "# 预期输出:\n",
    "# 解析结果1: {'id': '10234', 'name': 'Jane Smith', 'email': 'jane.s@example.com', 'status': 'active'}\n",
    "# 解析结果2: None\n",
    "# 解析结果3: {'id': '20567', 'name': 'Peter Jones', 'email': 'peter@work.net', 'status': 'inactive'}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 任务二：批量处理与数据分类\n",
    "\n",
    "现在你已经有了一个强大的解析函数，是时候用它来处理一批混合了有效和无效数据的记录了。你需要遍历所有原始数据，使用你创建的函数进行处理，并将结果分类存储。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- 数据处理完成 ---\n",
      "成功解析 3 条有效记录。\n",
      "发现 2 条无效记录。\n",
      "\n",
      "--- 有效用户信息 ---\n",
      "{'id': '33451', 'name': 'Alice Wonderland', 'email': 'alice.w@fantasy.net', 'status': 'pending'}\n",
      "{'id': '48912', 'name': 'Bob Builder', 'email': 'bob@const.com', 'status': 'active'}\n",
      "{'id': '55678', 'name': 'Diana Prince', 'email': 'diana@themyscira.org', 'status': 'active'}\n",
      "\n",
      "--- 无法解析的原始记录 ---\n",
      "This line is completely corrupted and has no valid data.\n",
      "Name: Charlie; Email: charlie@choco.factory; Status: Expired\n"
     ]
    }
   ],
   "source": [
    "raw_data_batch = [\n",
    "    \"ID: 33451; Name: ALICE wonderland; Email: alice.w@fantasy.net; Status: PENDING\",\n",
    "    \"   ID: 48912; Name: bob builder; Email:  BOB@CONST.COM; Status: Active   \",\n",
    "    \"This line is completely corrupted and has no valid data.\",\n",
    "    \"Name: Charlie; Email: charlie@choco.factory; Status: Expired\", # 缺少ID\n",
    "    \"ID: 55678; Name: diana prince; Email: diana@themyscira.org; Status: ACTIVE\"\n",
    "]\n",
    "\n",
    "valid_users = []\n",
    "invalid_records = []\n",
    "\n",
    "# 遍历 raw_data_batch\n",
    "# 1. 对每一条记录，调用你在任务一中创建的 parse_user_record 函数\n",
    "for record in raw_data_batch:\n",
    "    parsed_data = parse_user_record(record)\n",
    "    # 2. 如果函数返回一个字典，则将其添加到 valid_users 列表中\n",
    "    if parsed_data:\n",
    "        valid_users.append(parsed_data)\n",
    "    # 3. 如果函数返回 None，则将原始的、未处理的记录字符串添加到 invalid_records 列表中\n",
    "    else:\n",
    "        invalid_records.append(record)\n",
    "\n",
    "# --- 验证你的代码 ---\n",
    "print(f\"--- 数据处理完成 ---\")\n",
    "print(f\"成功解析 {len(valid_users)} 条有效记录。\")\n",
    "print(f\"发现 {len(invalid_records)} 条无效记录。\")\n",
    "print(\"\\n--- 有效用户信息 ---\")\n",
    "for user in valid_users:\n",
    "    print(user)\n",
    "print(\"\\n--- 无法解析的原始记录 ---\")\n",
    "for record in invalid_records:\n",
    "    print(record)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 任务三：生成格式化的CSV报告\n",
    "\n",
    "最后的挑战！作为数据处理的最终步骤，你需要将清洗好的 `valid_users` 数据转换成CSV（逗号分隔值）格式的字符串。CSV是一种通用的表格数据格式，可以被Excel等多种软件直接打开。\n",
    "\n",
    "**报告要求：**\n",
    "\n",
    "1.  **包含表头**：报告的第一行必须是表头，字段顺序为 `UserID,FullName,EmailAddress,Status`。\n",
    "2.  **数据对齐**：每一行数据应与表头字段一一对应。\n",
    "3.  **单字符串输出**：整个报告（包括表头和所有用户数据）最终应该是一个由换行符 `\\n` 连接起来的**单个字符串**。\n",
    "\n",
    "**预期输出（一个完整的字符串）：**\n",
    "```\n",
    "UserID,FullName,EmailAddress,Status\n",
    "33451,Alice Wonderland,alice.w@fantasy.net,pending\n",
    "48912,Bob Builder,bob@const.com,active\n",
    "55678,Diana Prince,diana@themyscira.org,active\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "--- 生成的CSV报告 ---\n",
      "UserID,FullName,EmailAddress,Status\n",
      "33451,Alice Wonderland,alice.w@fantasy.net,pending\n",
      "48912,Bob Builder,bob@const.com,active\n",
      "55678,Diana Prince,diana@themyscira.org,active\n"
     ]
    }
   ],
   "source": [
    "# (请先确保任务二已正确完成，valid_users 列表中包含了正确的数据)\n",
    "\n",
    "# 1. 定义表头\n",
    "csv_header = \"UserID,FullName,EmailAddress,Status\"\n",
    "\n",
    "# 2. 创建一个列表，用于存放报告的每一行，首先添加表头\n",
    "report_lines = [csv_header]\n",
    "\n",
    "# 遍历 valid_users 列表\n",
    "# 对于每一个用户字典:\n",
    "for user in valid_users:\n",
    "    # a. 提取 id, name, email, status 的值\n",
    "    # b. 使用 f-string 或 .join() 方法将这些值用逗号连接成一个字符串行\n",
    "    csv_line = f\"{user['id']},{user['name']},{user['email']},{user['status']}\"\n",
    "    # c. 将生成的字符串行添加到 report_lines 列表中\n",
    "    report_lines.append(csv_line)\n",
    "\n",
    "# 3. 使用 '\\n'.join() 将所有行合并成一个最终的报告字符串\n",
    "final_report = \"\\n\".join(report_lines)\n",
    "\n",
    "# --- 打印最终报告 ---\n",
    "print(\"--- 生成的CSV报告 ---\")\n",
    "print(final_report)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 实验结束\n",
    "\n",
    "干得漂亮！你已经完成了一个从混乱到有序的完整数据处理流程。这个实验不仅巩固了你的字符串操作能力，还让你体验了编程在解决实际问题中的强大作用。这些技能在未来的数据科学、软件开发等领域都至关重要。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}